package com.arcaneshift.model.validators;

import java.util.List;

import com.arcaneshift.model.abstracts.AbstractCard;
import com.arcaneshift.model.action.game.CreatureCard;
import com.arcaneshift.model.action.game.SpellCard;
import com.arcaneshift.model.request.AddDeckRequest;
import com.arcaneshift.model.util.CardType;
import com.arcaneshift.security.errors.DeckError;
import com.common.model.abstracts.AbstractRequest;
import com.common.model.abstracts.AbstractValidator;
import com.common.security.abstracts.AbstractError;

public class AddDeckValidator extends AbstractValidator {

	private static final int NAME_MIN_LENGTH = 1;
	private static final int NAME_MAX_LENGTH = 200;
	
	private static final CreatureCardValidator creatureValidator = new CreatureCardValidator();
	private static final SpellCardValidator spellValidator = new SpellCardValidator();
	
	@Override
	public boolean validate(AbstractRequest abstractRequest) {
		AddDeckRequest request = null;
		
		if (abstractRequest instanceof AddDeckRequest) {
			request = (AddDeckRequest) abstractRequest;
		} else {
			error = new DeckError(AbstractError.INVALID_REQUEST);
			return false;
		}
		
		String name = request.getName();
		if (name == null) {
			error = new DeckError(DeckError.NO_NAME_PROVIDED);
			return false;
		}
		
		if (name.length() < AddDeckValidator.NAME_MIN_LENGTH || 
				name.length() > AddDeckValidator.NAME_MAX_LENGTH) {
			error = new DeckError(DeckError.NAME_BAD_FORMAT);
			return false;
		}
		
		List<AbstractCard> cards = request.getCards();
		
		if (cards == null || cards.size() == 0) {
			error = new DeckError(DeckError.EMPTY_DECK);
			return false;
		}
		
		return validateCards(cards);
	}
	
	private boolean validateCards(List<AbstractCard> cards) {
		for (AbstractCard card : cards) {
			if (card.getType().equals(CardType.CREATURE)) {
				if (!creatureValidator.validate((CreatureCard) card)) {
					this.error = creatureValidator.getError();
					return false;
				}
			} else if (card.getType().equals(CardType.SPELL)) {
				if (!spellValidator.validate((SpellCard) card)) {
					this.error = spellValidator.getError();
					return false;
				}
			}
		}
		return true;
	}
}
